home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.4 / AppShell / Examples / Clipboard / clipiff.c next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  19.7 KB  |  828 lines

  1. /*************************************************************************
  2.   *                                                                      *
  3.   *                            Preliminary                               *
  4.   *                        Amiga AppShell (tm)                           *
  5.   *                                                                      *
  6.   *  Copyright (c) 1990,1991 Commodore-Amiga, Inc. All Rights Reserved.  *
  7.   *                                                                      *
  8.   *   This software and information is proprietary, preliminary, and     *
  9.   *   subject to change without notice.                                  *
  10.   *                                                                      *
  11.   *                            DISCLAIMER                                *
  12.   *                                                                      *
  13.   *   THIS SOFTWARE IS PROVIDED "AS IS".                                 *
  14.   *   NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE      *
  15.   *   ACCURACY, RELIABILITY, PERFORMANCE, CURRENTNESS, OR OPERATION      *
  16.   *   OF THIS SOFTWARE, AND ALL USE IS AT YOUR OWN RISK.                 *
  17.   *   NEITHER COMMODORE NOR THE AUTHORS ASSUME ANY RESPONSIBILITY OR     *
  18.   *   LIABILITY WHATSOEVER WITH RESPECT TO YOUR USE OF THIS SOFTWARE.    *
  19.   *                                                                      *
  20.   *                          Non-Disclosure                              *
  21.   *                                                                      *
  22.   *   This information is not to be disclosed to any other company,      *
  23.   *   individual or party.  Discussion is to be restricted to CBM        *
  24.   *   approved discussion areas, such as the closed conferences on bix;  *
  25.   *   amiga.cert, amiga.com, amiga.beta/appshell.                        *
  26.   *                                                                      *
  27.   ************************************************************************
  28.   */
  29.  
  30. /* clipiff.c
  31.  * Simple IFF FTXT clipboard routines, requires iffparse.library version 36.
  32.  * Copyright (C) 1990 Commodore-Amiga, Inc.
  33.  * written by David N. Junod, 26-Aug-90
  34.  *
  35.  * Compiled with Lattice 'C' version 5.05.
  36.  *
  37.  *    LC -cqfist -ms -v clipiff
  38.  */
  39.  
  40. #include <exec/types.h>
  41. #include <exec/libraries.h>
  42. #include <exec/memory.h>
  43. #include <exec/io.h>
  44. #include <dos/dos.h>
  45. #include <dos/dosextens.h>
  46. #include <devices/clipboard.h>
  47. #include <libraries/iffparse.h>
  48. #include <utility/hooks.h>
  49. #include <clib/exec_protos.h>
  50. #include <clib/iffparse_protos.h>
  51. #include <pragmas/exec.h>
  52. #include <pragmas/iffparse.h>
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55. #include <string.h>
  56. #include "clipiff.h"
  57.  
  58. extern struct Library *SysBase, *UtilityBase;
  59.  
  60. #define CLIP_ERROR    FALSE
  61.  
  62. struct ClipManager *__asm AllocClip (VOID)
  63. {
  64.     struct ClipManager *cm;
  65.     ULONG hookEntry();
  66.  
  67.     /* Attempt to allocate the ClipManager structure */
  68.     if (cm = (struct ClipManager *)
  69.     AllocMem (sizeof (struct ClipManager), MEMF_CLEAR))
  70.     {
  71.     /* Are we using 2.0 or greater? */
  72.     if (SysBase->lib_Version >= 36)
  73.     {
  74.         /* Initialize the hook */
  75.         cm->cm_Hook.h_Entry = hookEntry;
  76.         cm->cm_Hook.h_Data = (VOID *) 0xFACE;
  77.     }
  78.  
  79.     /* Indicate that there isn't a hook installed */
  80.     cm->cm_HookUnit = (-1L);
  81.     }
  82.  
  83.     /* Return the initialized ClipManager */
  84.     return (cm);
  85. }
  86.  
  87. VOID __asm FreeClip (register __a1 struct ClipManager * cm)
  88. {
  89.  
  90.     /* Make sure we at least have a pointer */
  91.     if (cm)
  92.     {
  93.     WORD i;
  94.  
  95.     /* See if there is a hook installed */
  96.     if (cm->cm_HookUnit >= 0L)
  97.     {
  98.         /* Stop the hook */
  99.         StopClipChangeHook (cm);
  100.     }
  101.  
  102.     /* Shutdown each open clipboard unit */
  103.     for (i = 0; i < MAX_UNITS; i++)
  104.         CloseClip (cm->cm_Unit[i]);
  105.  
  106.     /* Free each open clipboard buffer */
  107.     for (i = 0; i < MAX_UNITS; i++)
  108.         FreeBuffer (cm->cm_Buff[i]);
  109.  
  110.     /* Free the clipboard manager */
  111.     FreeMem (cm, sizeof (struct ClipManager));
  112.  
  113.     }                /* End of if ClipManager */
  114. }
  115.  
  116. struct ClipBuff * __asm ReadClip (
  117.     register __a1 struct ClipManager * cm,
  118.     register __d0 LONG iff_type,
  119.     register __d1 LONG id)
  120. {
  121.     struct ClipBuff *buffer = NULL;
  122.     struct IFFHandle *iff = NULL;
  123.  
  124.     /* make sure we have a pointer at least */
  125.     if (cm)
  126.     {
  127.     /* Make sure we have a valid clipboard unit */
  128.     if ((id >= 0L) && (id < MAX_UNITS))
  129.     {
  130.         /* Open the requested clipboard unit if it isn't already */
  131.         if (!(cm->cm_Unit[id]))
  132.         {
  133.         cm->cm_Unit[id] = OpenClip (id);
  134.         }
  135.  
  136.         /* Free the buffer */
  137.         FreeBuffer (cm->cm_Buff[id]);
  138.         cm->cm_Buff[id] = NULL;
  139.  
  140.         /* Make sure we have a clipboard unit to work with */
  141.         if (iff = cm->cm_Unit[id])
  142.         {
  143.         switch (iff_type)
  144.         {
  145.             case 0L:    /* Default to FTXT */
  146.             case ID_FTXT:
  147.             buffer = ReadFTXT (iff);
  148.             break;
  149.  
  150.             default:
  151.             break;
  152.         }
  153.  
  154.         /* assign the buffer */
  155.         cm->cm_Buff[id] = buffer;
  156.  
  157.         }            /* End of if unit available */
  158.     }            /* End of if >= 0 and < MAX_UNITS */
  159.     }                /* End of if ClipManager pointer */
  160.  
  161.     return (buffer);
  162. }
  163.  
  164. LONG __asm QueryClip (
  165.     register __a1 struct ClipManager * cm,
  166.     register __d0 LONG unit,
  167.     register __a2 ULONG *ctype,
  168.     register __a3 ULONG *clipid)
  169. {
  170.     LONG retval = FALSE;
  171.  
  172.     if (cm)
  173.     {
  174.     struct IFFHandle *iff;
  175.  
  176.     /* Open the requested clipboard unit if it isn't already */
  177.     if (!(cm->cm_Unit[unit]))
  178.     {
  179.         cm->cm_Unit[unit] = OpenClip (unit);
  180.     }
  181.  
  182.     /* Make sure we have a clipboard unit to work with */
  183.     if (iff = cm->cm_Unit[unit])
  184.     {
  185.         struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
  186.         struct IOClipReq *clipIO = &(cbh->cbh_Req);
  187.         LONG cbuff[5] = {NULL};
  188.  
  189.         /* Read clipboard header */
  190.         clipIO->io_Command = CMD_READ;
  191.         clipIO->io_Error = 0;
  192.         clipIO->io_ClipID = 0;
  193.         clipIO->io_Offset = 0;
  194.         clipIO->io_Data = (char *) cbuff;
  195.         clipIO->io_Length = 20;
  196.         DoIO (clipIO);
  197.  
  198.         /* Fill in the clip ID */
  199.         *clipid = (ULONG) clipIO->io_ClipID;
  200.  
  201.         /* Clear the type field */
  202.         *ctype = 0L;
  203.  
  204.         /* See if the read was successful */
  205.         if ((clipIO->io_Actual >= 8L) && (cbuff[2] != ID_SPACE))
  206.         {
  207.         /* Fill in the type field */
  208.         *ctype = (ULONG) cbuff[2];
  209.         }
  210.  
  211.         /* indicate that we're done reading */
  212.         clipIO->io_Offset = 0x7FFFFFF0;
  213.         clipIO->io_Length = 1;
  214.         clipIO->io_Data = NULL;
  215.         DoIO (clipIO);
  216.  
  217.         /* Indicate success */
  218.         retval = TRUE;
  219.     }
  220.     }
  221.  
  222.     return (retval);
  223. }
  224.  
  225. /* This hook must do the least amount of work as possible. It is done on the
  226.  * clipboard.device task frame */
  227. ULONG clipHook (struct Hook *h, VOID *o, struct ClipHookMsg *msg)
  228. {
  229.     if (h->h_Data)
  230.     {
  231.     Signal ((struct Task *)h->h_Data, SIGBREAKF_CTRL_E);
  232.     }
  233.  
  234.     return (0L);
  235. }
  236.  
  237. LONG __asm StartClipChangeHook (
  238.     register __a1 struct ClipManager * cm,
  239.     register __d0 LONG unit)
  240. {
  241.     LONG retval = FALSE;
  242.  
  243.     if (cm)
  244.     {
  245.     struct IFFHandle *iff;
  246.  
  247.     /* Open the requested clipboard unit if it isn't already */
  248.     if (!(cm->cm_Unit[unit]))
  249.     {
  250.         cm->cm_Unit[unit] = OpenClip (unit);
  251.     }
  252.  
  253.     /* Make sure we don't have any outstanding hooks */
  254.     StopClipChangeHook (cm);
  255.  
  256.     /* Make sure we have a clipboard unit to work with */
  257.     if (iff = cm->cm_Unit[unit])
  258.     {
  259.         struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
  260.         struct IOClipReq *clipIO = &(cbh->cbh_Req);
  261.         extern ULONG hookEntry();
  262.  
  263.         /* Fill out the IO request */
  264.         clipIO->io_Command = CBD_CHANGEHOOK;
  265.         clipIO->io_Data = (char *) &(cm->cm_Hook);
  266.         clipIO->io_Length = 1;
  267.  
  268.         /* Prepare the hook */
  269.         cm->cm_Hook.h_Entry = hookEntry;
  270.         cm->cm_Hook.h_SubEntry = clipHook;
  271.         cm->cm_Hook.h_Data = FindTask (NULL);
  272.  
  273.         /* Start the hook */
  274.         if (DoIO (clipIO))
  275.         {
  276.         /* printf ("unable to set hook\n"); */
  277.         }
  278.         else
  279.         {
  280.         /* Indicate success */
  281.         cm->cm_HookUnit = unit;
  282.  
  283.         retval = TRUE;
  284.         }
  285.     }
  286.     }
  287.  
  288.     return (retval);
  289. }
  290.  
  291. LONG __asm StopClipChangeHook (register __a1 struct ClipManager * cm)
  292. {
  293.     LONG retval = FALSE;
  294.  
  295.     if (cm && (cm->cm_HookUnit >= 0L))
  296.     {
  297.     LONG unit = cm->cm_HookUnit;
  298.     struct IFFHandle *iff;
  299.  
  300.     /* Open the requested clipboard unit if it isn't already */
  301.     if (!(cm->cm_Unit[unit]))
  302.     {
  303.         cm->cm_Unit[unit] = OpenClip (unit);
  304.     }
  305.  
  306.     /* Make sure we have a clipboard unit to work with */
  307.     if (iff = cm->cm_Unit[unit])
  308.     {
  309.         struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
  310.         struct IOClipReq *clipIO = &(cbh->cbh_Req);
  311.  
  312.         /* Fill out the IO request */
  313.         clipIO->io_Command = CBD_CHANGEHOOK;
  314.         clipIO->io_Data = (char *) &(cm->cm_Hook);
  315.         clipIO->io_Length = 0;
  316.  
  317.         /* Start the hook */
  318.         if (DoIO (clipIO))
  319.         {
  320.         /* printf ("unable to stop hook\n"); */
  321.         }
  322.         else
  323.         {
  324.         /* Indicate success */
  325.         retval = TRUE;
  326.         }
  327.     }
  328.  
  329.     /* Indicate that the hook has been halted */
  330.     cm->cm_HookUnit = (-1L);
  331.     }
  332.  
  333.     return (retval);
  334. }
  335.  
  336. LONG __asm WriteClip (
  337.     register __a1 struct ClipManager * cm,
  338.     register __a2 struct ClipBuff * buff,
  339.     register __d0 LONG id)
  340. {
  341.     LONG retval = 0L;
  342.  
  343.     /* make sure we have a pointer at least */
  344.     if (cm && buff)
  345.     {
  346.     struct IFFHandle *iff = NULL;
  347.  
  348.     /* Make sure we have a valid clipboard unit */
  349.     if ((id >= 0L) && (id < MAX_UNITS))
  350.     {
  351.         /* Open the requested clipboard unit if it isn't already */
  352.         if (!(cm->cm_Unit[id]))
  353.         cm->cm_Unit[id] = OpenClip (id);
  354.  
  355.         /* Make sure we have a clipboard unit to work with */
  356.         if (iff = cm->cm_Unit[id])
  357.         {
  358.         switch (buff->b_Type)
  359.         {
  360.             case 0L:    /* Default to FTXT */
  361.             case ID_FTXT:
  362.             retval = WriteFTXT (iff, buff->b_Buff);
  363.             break;
  364.  
  365.             default:
  366.             break;
  367.         }
  368.         }            /* End of if unit available */
  369.     }            /* End of if >= 0 and < MAX_UNITS */
  370.  
  371.     /* Assign the clip ID assigned to this write */
  372.     buff->b_ClipID = retval;
  373.     }                /* End of if ClipManager pointer */
  374.  
  375.     return (retval);
  376. }
  377.  
  378. /****** clip/OpenClip *********************************************************
  379. *
  380. *   NAME
  381. *    OpenClip - Obtain an IFF handle on the desired clipboard unit.
  382. *
  383. *   SYNOPSIS
  384. *    handle = OpenClip ( clip_id );
  385. *    d0            d0
  386. *
  387. *    struct IFFHandle *handle;
  388. *    LONG clip_id;
  389. *
  390. *   FUNCTION
  391. *    Obtain a handle on a particular clipboard unit for reading and
  392. *    writing of data.
  393. *
  394. *   INPUTS
  395. *    clip_id    - A number from 0 to 255, used to indicate the clipboard
  396. *          unit to use.  For normal useage, PRIMARY_CLIP should
  397. *          be used.
  398. *
  399. *   RETURNS
  400. *    handle    - Returns a valid IFFHandle to use for further access
  401. *          or NULL if unable to access the requested unit.
  402. *
  403. *   SEE ALSO
  404. *    CloseClip()
  405. *
  406. **********************************************************************
  407. *
  408. * Created:  26-Aug-90, David N. Junod
  409. *
  410. */
  411.  
  412. struct IFFHandle *__asm OpenClip (register __d0 LONG id)
  413. {
  414.     struct IFFHandle *iff = NULL;
  415.  
  416.     /* Allocate an IFF handle */
  417.     if (iff = AllocIFF ())
  418.     {
  419.     /* Open the clipboard for access */
  420.     if (iff->iff_Stream = (ULONG) OpenClipboard (id))
  421.     {
  422.         /* Initialize the handle as clipboard access */
  423.         InitIFFasClip (iff);
  424.     }
  425.     else
  426.     {
  427.         /* Free the IFF handle */
  428.         FreeIFF (iff);
  429.         iff = NULL;
  430.     }
  431.     }
  432.  
  433.     return (iff);
  434. }
  435.  
  436. /****** clip/CloseClip ********************************************************
  437. *
  438. *   NAME
  439. *    CloseClip - Close an IFF handle obtained by OpenClip().
  440. *
  441. *   SYNOPSIS
  442. *    CloseClip ( handle );
  443. *            a0
  444. *
  445. *    struct IFFHandle *handle;
  446. *
  447. *   FUNCTION
  448. *    Used to close a IFF handle opened by OpenClip() only.
  449. *
  450. *   INPUTS
  451. *    handle    - A valid IFFHandle obtained by calling OpenClip().
  452. *
  453. *   SEE ALSO
  454. *    OpenClip()
  455. *
  456. **********************************************************************
  457. *
  458. * Created:  26-Aug-90, David N. Junod
  459. *
  460. */
  461.  
  462. VOID __asm CloseClip (register __a1 struct IFFHandle * iff)
  463. {
  464.  
  465.     /* Make sure that the handle points to something */
  466.     if (iff)
  467.     {
  468.     /* Close the clipboard */
  469.     if (iff->iff_Stream)
  470.         CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream);
  471.  
  472.     /* Free the IFF handle */
  473.     FreeIFF (iff);
  474.     }
  475. }
  476.  
  477. /****** clip/FreeBuffer *******************************************************
  478. *
  479. *   NAME
  480. *    FreeBuffer - Used to free a buffer returned by ReadClip().
  481. *
  482. *   SYNOPSIS
  483. *    FreeBuffer ( buffer );
  484. *             a0
  485. *
  486. *    struct ClipBuff *buffer;
  487. *
  488. *   FUNCTION
  489. *    This function is used to free the memory allocated by a call to
  490. *    ReadClip().
  491. *
  492. *   INPUTS
  493. *    buffer    - A valid buffer pointer returned by a call to ReadClip().
  494. *
  495. *   SEE ALSO
  496. *    ReadFTXT()
  497. *
  498. **********************************************************************
  499. *
  500. * Created:  26-Aug-90, David N. Junod
  501. *
  502. */
  503.  
  504. VOID __asm FreeBuffer (register __a1 struct ClipBuff * buff)
  505. {
  506.  
  507.     /* Make sure that buffer is a pointer, not an error */
  508.     if ((LONG) buff > 0L)
  509.     {
  510.     /* Free the entire buffer */
  511.     FreeMem ((APTR) buff, buff->b_Size);
  512.     }
  513. }
  514.  
  515. /****** clip/ReadFTXT *********************************************************
  516. *
  517. *   NAME
  518. *    ReadFTXT - Read the IFF handle for FTXT.
  519. *
  520. *   SYNOPSIS
  521. *    buffer = ReadFTXT ( handle );
  522. *    d0            a0
  523. *
  524. *    struct ClipBuff *buffer;
  525. *    struct IFFHandle *handle;
  526. *
  527. *   FUNCTION
  528. *    Read the passed IFF handle for the first occurrance of FTXT CHRS
  529. *    and returns the characters in a buffer.
  530. *
  531. *   INPUTS
  532. *    handle    - A valid IFF handle, returned by OpenClip().
  533. *
  534. *   RETURNS
  535. *    buffer    - If greater than zero, then it is a pointer to a ClipBuff
  536. *          structure that contains the contents of the FTXT CHRS
  537. *          chunk first encountered.
  538. *
  539. *          If buffer is less than zero, then an error occurred and
  540. *          the following macros are used to indicate the error.
  541. *
  542. *          RC_EMPTY_CLIP        \* clipboard is empty *\
  543. *          RC_NOT_ENOUGH_MEMORY    \* not enough memory *\
  544. *                 RC_COULDNT_READ    \* couldn't read a chunk *\
  545. *                 RC_BAD_IFF        \* clipboard contains a bad IFF *\
  546. *                 RC_INVALID_TYPE    \* don't understand FORM type *\
  547. *
  548. *   SEE ALSO
  549. *    FreeBuffer()
  550. *
  551. **********************************************************************
  552. *
  553. * Created:  26-Aug-90, David N. Junod
  554. *
  555. */
  556.  
  557. LONG ftxtprops[] = {ID_FTXT, ID_AUTH, ID_FTXT, ID_NAME};
  558.  
  559. struct ClipBuff *__asm
  560. ReadFTXT (register __a1 struct IFFHandle * iff)
  561. {
  562.     struct ClipBuff *b = NULL;
  563.     LONG error = 0L;
  564.  
  565.     /* Make sure that the handle points to something */
  566.     if (iff)
  567.     {
  568.     struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
  569.     struct IOClipReq *clipIO = &(cbh->cbh_Req);
  570.  
  571.     if (((struct Library *) IFFParseBase)->lib_Version < 36)
  572.     {
  573.         /* Bug workaround: clear io_Error field */
  574.         clipIO->io_Error = 0;
  575.  
  576.         /* Bug workaround: Turn off the write flag */
  577.         iff->iff_Flags &= ~IFFF_WRITE;
  578.     }
  579.  
  580.     /* Open the IFF handle for reading */
  581.     if (!(error = OpenIFF (iff, IFFF_READ)))
  582.     {
  583.         /* Declare the properties to search for */
  584.         PropChunks (iff, ftxtprops, 2);
  585.  
  586.         /* Register the stop chunk */
  587.         if ((error = StopChunk (iff, ID_FTXT, ID_CHRS)) == 0L)
  588.         {
  589.         /* Parse the file, stopping at a character chunk */
  590.         error = ParseIFF (iff, IFFPARSE_SCAN);
  591.         }
  592.  
  593.         /* Check the return value */
  594.         if (error == IFFERR_EOF || error == IFFERR_NOTIFF)
  595.         {
  596.         b = (struct ClipBuff *) RC_EMPTY_CLIP;
  597.         }
  598.         else if (error != 0L)
  599.         {
  600.         b = (struct ClipBuff *) RC_BAD_IFF;
  601.         }
  602.         else
  603.         {
  604.         struct ContextNode *cn;
  605.         LONG msize;
  606.  
  607.         /* Get information on the current chunk */
  608.         if ((cn = CurrentChunk (iff)) && (cn->cn_Size > 0L))
  609.         {
  610.             /* Calculate the size of our buffer */
  611.             msize = sizeof (struct ClipBuff) + cn->cn_Size + 1;
  612.  
  613.             /* Allocate a buffer to place our text in */
  614.             if (b = (struct ClipBuff *) AllocMem (msize, MEMF_CLEAR))
  615.             {
  616.             /* Point the contents buffer at the right place */
  617.             b->b_Buff = (VOID *) ((b) + 1);
  618.  
  619.             /* Read in the characters */
  620.             if ((error = ReadChunkBytes (iff, b->b_Buff, cn->cn_Size))
  621.                 == cn->cn_Size)
  622.             {
  623.                 /* Remember the buffer size */
  624.                 b->b_Size = msize;
  625.  
  626.                 /* Remember the type of buffer */
  627.                 b->b_Type = ID_FTXT;
  628.  
  629.                 /* Get the current clip ID */
  630.                 b->b_ClipID = clipIO->io_ClipID;
  631.  
  632. #if 0
  633.                 struct StoredProperty *sp;
  634.  
  635.                 /* Get the author information */
  636.                 if (sp = FindProp (iff, ID_FTXT, ID_AUTH))
  637.                 {
  638.                 msize = sp->sp_Size + 1L;
  639.  
  640.                 if (b->b_Author = (STRPTR) AllocMem (msize, MEMF_CLEAR))
  641.                 {
  642.                     b->b_ASize = msize;
  643.                     strcpy (b->b_Author, sp->sp_Data);
  644.                 }
  645.                 }
  646.  
  647.                 /* Get the project information */
  648.                 if (sp = FindProp (iff, ID_FTXT, ID_NAME))
  649.                 {
  650.                 msize = sp->sp_Size + 1L;
  651.  
  652.                 if (b->b_Project = (STRPTR) AllocMem (msize, MEMF_CLEAR))
  653.                 {
  654.                     b->b_PSize = msize;
  655.                     strcpy (b->b_Project, sp->sp_Data);
  656.                 }
  657.                 }
  658. #endif
  659.             }
  660.             else
  661.             {
  662.                 /* Free the buffer */
  663.                 FreeMem ((APTR) b, msize);
  664.                 b = (struct ClipBuff *) RC_COULDNT_READ;
  665.             }
  666.             }        /* End of if allocate buffer */
  667.             else
  668.             {
  669.             b = (struct ClipBuff *) RC_NOT_ENOUGH_MEMORY;
  670.             }
  671.  
  672.         }        /* End of get current chunk info */
  673.         else
  674.         {
  675.             b = (struct ClipBuff *) RC_COULDNT_READ;
  676.         }
  677.  
  678.         }            /* End of handle parse */
  679.  
  680.         /* Say that we're done reading */
  681.         CloseIFF (iff);
  682.     }
  683.     else
  684.     {
  685.         b = (struct ClipBuff *) error;
  686.     }
  687.  
  688.     }                /* End of if there is a handle */
  689.  
  690.     return (b);
  691. }
  692.  
  693. /****** clip/WriteChunk *******************************************************
  694. *
  695. *   NAME
  696. *    WriteChunk - Used to write a text chunk.
  697. *
  698. *   SYNOPSIS
  699. *    error = WriteChunk ( handle, chunk, text );
  700. *    d0             a0      d0     a1
  701. *
  702. *    LONG error;
  703. *    struct IFFHandle *handle;
  704. *    LONG chunk;
  705. *    STRPTR text;
  706. *
  707. *   FUNCTION
  708. *    This function is used to write out a text chunk, such as ANNO, AUTH
  709. *    or CHRS.
  710. *
  711. *   INPUTS
  712. *    handle    - A valid IFF handle, returned by OpenClip()
  713. *
  714. *    chunk    - A chunk type that supports text, such as ID_ANNO, ID_AUTH,
  715. *          ID_CHRS, ID_(c) or ID_NAME.
  716. *
  717. *    text    - A pointer to a NULL terminated buffer that contains the
  718. *          text to write.
  719. *
  720. *   RETURNS
  721. *    error    - A value of zero indicates that no errors occurred. A non-
  722. *          zero value indicates an error.  Values are defined in
  723. *          <libraries/iffparse.h>.
  724. *
  725. **********************************************************************
  726. *
  727. * Created:  26-Aug-90, David N. Junod
  728. *
  729. */
  730.  
  731. LONG __asm WriteChunk (
  732.                     register __a1 struct IFFHandle * iff,
  733.                     register __d0 LONG id,
  734.                     register __a2 STRPTR buffer)
  735. {
  736.     LONG error = 0L;
  737.     LONG clen = (LONG) strlen (buffer) + 1;
  738.  
  739.     if (buffer && (clen > 0L))
  740.     {
  741.     if ((error = PushChunk (iff, 0, id, -1L)) == 0L)
  742.     {
  743.         if ((error = WriteChunkBytes (iff, buffer, clen)) > 0L)
  744.         {
  745.         error = PopChunk (iff);
  746.         }
  747.     }
  748.     }
  749.  
  750.     return (error);
  751. }
  752.  
  753. /****** clip/WriteFTXT ********************************************************
  754. *
  755. *   NAME
  756. *    WriteFTXT - Write an IFF form that contains text.
  757. *
  758. *   SYNOPSIS
  759. *    error = WriteFTXT ( handle, text );
  760. *    d0            a0        a1
  761. *
  762. *    LONG error;
  763. *    struct IFFHandle *handle;
  764. *    STRPTR text;
  765. *
  766. *   FUNCTION
  767. *    This function is used to write an IFF form that contains text.
  768. *
  769. *   INPUTS
  770. *    handle    - A valid IFF handle, returned by OpenClip()
  771. *    text    - A pointer to a NULL terminated buffer that contains the
  772. *          text to write.
  773. *
  774. *    RETURNS
  775. *    error    - A value of zero indicates that no errors occurred. A
  776. *          negative number indicates an error (values are defined
  777. *          in <libraries/iffparse.h>.  A positive number indicates
  778. *          the clip ID assigned to the clip.
  779. *
  780. *   SEE ALSO
  781. *    ReadFTXT()
  782. *
  783. **********************************************************************
  784. *
  785. * Created:  26-Aug-90, David N. Junod
  786. *
  787. */
  788.  
  789. LONG __asm
  790. WriteFTXT (register __a1 struct IFFHandle * iff, register __a2 STRPTR buffer)
  791. {
  792.     LONG retval = 0L;
  793.  
  794.     if (iff)
  795.     {
  796.     struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
  797.     struct IOClipReq *clipIO = &(cbh->cbh_Req);
  798.  
  799.     if (((struct Library *) IFFParseBase)->lib_Version < 36)
  800.     {
  801.         /* Bug workaround: clear io_Error field */
  802.         clipIO->io_Error = 0;
  803.     }
  804.  
  805.     /* Open the IFF handle for writing */
  806.     if ((retval = OpenIFF (iff, IFFF_WRITE)) == 0L)
  807.     {
  808.         /* Start writing the text ... */
  809.         if ((retval = PushChunk (iff, ID_FTXT, ID_FORM, -1L)) == 0)
  810.         {
  811.         /* Write out the buffer as characters */
  812.         WriteChunk (iff, ID_CHRS, buffer);
  813.  
  814.         /* Finish out the entire write */
  815.         PopChunk (iff);
  816.  
  817.         /* Assign the clip ID */
  818.         retval = clipIO->io_ClipID;
  819.         }
  820.  
  821.         /* Say that we're done writing */
  822.         CloseIFF (iff);
  823.     }
  824.     }
  825.  
  826.     return (retval);
  827. }
  828.